package Features;

@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK =  qw(%myvariable %cacheDicewd %cacheDicert %cacheDicewdnull %cacheDicertnull %cacheDict %cacheBasicEngHnd %cacheBasicHndEng 
		%cacheRootEngHnd %cacheRootHndEng %cacheMI %Dicewd %Dicert %Dicewdnull %Dicertnull %Dict %BasicEngHnd %BasicHndEng 
	        %RootEngHnd %RootHndEng %MI);

sub new {
	my($this) = {};
	bless $this;
	return $this;
}

sub valid_rel {
        my($prep) = shift;              
        my(@relations) = ("subj","obj","by","on","in","into","at","for","through","with","without","of","to","after","around","during","beneath","behind","from","adj","at","from","over","about","under","before","within","against","since","until","upon","among","despite","along","beyond","than","above","near","below","onto","inside","amongst","towards","besides");
        foreach $rel (@relations)
        {
                if($rel eq $prep)
                { return 1; }
        }
        return 0;
        
}            

sub get_depdirec {
	my($this) = shift;
	my($Dep) = shift;
	my($wordpos) = shift;
	my($Align) = shift;
	my($engsen) = shift;
	my($hinsen) = shift;
	my($nengwords) = $#{$engsen->{'word'}}+1;
	my($nhinwords) = $#{$hinsen->{'word'}}+1;
	my($childpos);
	my($t,$dist);
	my($pPOS,$cPOS);
	my($wordaln,$childaln);

	$pPOS = $engsen->{'pos'}->[$wordpos];
	$wordaln = $Align->{'aln'}->[$wordpos];
	$tpPOS = $hinsen->{'pos'}->[$wordaln];
	$pPOS=~/^(.)/; $truncpPOS = $1;

	my($minaln,$maxaln);
	$maxaln = $wordaln;
	$minaln = $wordaln;

	my($GCONF) = $ENV{'GCONF'};

	for($t=0;$t<$Dep->[$wordpos]->{'noatt'};$t++)
	{
		$childpos = $Dep->[$wordpos]->{'attch'}->[$t];
		$cPOS = $engsen->{'pos'}->[$childpos];
		$childaln = $Align->{'aln'}->[$childpos];
		$tcPOS = $hinsen->{'pos'}->[$childpos];
		$cPOS=~/^(.)/; $trunccPOS = $1;


		if($pPOS ne "" && $cPOS ne "" && $wordaln ne "-" && $childaln ne "-")
		{
			if($wordpos>$childpos)
			{
				$srcstr = $cPOS."_".$pPOS;	
			}
			else
			{
				$srcstr = $pPOS."_".$cPOS;	
			}

			$dist = $wordaln - $childaln;

			if($dist>0)
			{
				$tgtstr = $tcPOS."_".$tpPOS;

				$this->{"childbefore_$truncpPOS\_$trunccPOS"}+=1;	
				#print "chbefore_$pPOS\_$cPOS\n";
			}
			elsif($dist<0)
			{
				$tgtstr = $tpPOS."_".$tcPOS;

				$this->{"childafter_$truncpPOS\_$trunccPOS"}+= 1;
				#print "chafter_$pPOS\_$cPOS\n";
			}
			else
			{
				#$tgtstr = $tcPOS;
				$this->{"childmerge_$truncpPOS\_$trunccPOS"}+= 1;
				#print "chmerge_$pPOS\_$cPOS\n";
			}
			#$this->{"pat_$srcstr\_$tgtstr"}+= 1;
			#$this->{"avgdist"}+= abs($dist);

		}

		if($childaln ne "-" && $childaln<$minaln) { $minaln = $childaln; }
		elsif($childaln ne "-" && $childaln>$maxaln) { $maxaln = $childaln; }

=cut
		elsif($wordaln eq "-" && $childaln eq "-")
		{
			$this->{"bothNull_$pPOS\_$cPOS"}+= 1;
		}
		elsif($wordaln eq "-")
		{
			$this->{"parenNull_$pPOS\_$cPOS"}+= 1;
		}
		elsif($childaln eq "-")
		{
			$this->{"childNull_$pPOS\_$cPOS"}+= 1;
		}
=cut
		$this->get_depdirec($Dep,$childpos,$Align,$engsen,$hinsen);
		
	}
	if($GCONF==11) {
		$this->{'avgspan'} += $maxaln - $minaln;
	}
}

sub getGFeatures {
	my($this) = shift;
	my($engsen) = shift;
	my($hinsen) = shift;
	my($Align) = shift;
	my($Varg) = shift;
	my($Dep) = shift;
	my($nengwords) = $#{$engsen->{'word'}}+1;
	my($nhinwords) = $#{$hinsen->{'word'}}+1;

        my($i,$j,$p);
        my($avvb_dist,$av,$tot,$overlap);

	my($GCONF) = $ENV{'GCONF'};


	$overlap = 0;
	$total = 0;
	my(%numberpos);
	my($nonnulls) = 0;

	for($i=0;$i<$nengwords;$i++)
	{
		if($Align->{'aln'}->[$i] ne "-")
		{
			$numberpos{$Align->{'aln'}->[$i]}++;
	#		print STDERR $i." ".$Align->{'aln'}->[$i]." ".$numberpos{$npos}."\n";
		}
	}

	foreach $npos (keys %numberpos)
	{
		if($numberpos{$npos}>1)
		{ $overlap+=$numberpos{$npos}*$numberpos{$npos}; }

		$nonnulls++;


		$total+= $numberpos{$npos};
	}

	if($GCONF==8 || $GCONF==10 || $GCONF==11) {
		if($total)
		{ $this->{'overlap'} = $overlap/$total; }
	}

	if($GCONF==11) {
		$this->{'nulls'} = ($nhinwords-$nonnulls)/$nhinwords;
	}
	#print STDERR "$overlap $total Nonnulls=$nonnulls Hindiwords=$nhinwords\n";

	if($GCONF==11) {
		my($rootpos,$roothinpos);
		$rootpos = $Dep->[0]->{'root'};
		if($Align->{'aln'}->[$rootpos])
		{ $this->{"rootpos"} = $Align->{'aln'}->[$rootpos]/$nhinwords; }
	}

	if($GCONF==9 || $GCONF==10 || $GCONF==11) {
		#$this->get_depdirec1($Dep,$rootpos,$Align,$engsen,$hinsen);
		#$this->get_depdirec1($Dep,$rootpos,$Align,$engsen,$hinsen);
		#$this->get_depdirec1($Dep,$rootpos,$Align,$engsen,$hinsen);
		#$this->get_depdirec1($Dep,$rootpos,$Align,$engsen,$hinsen);
	}

	if($GCONF==11) {
		$this->{'avgspan'}/=$nhinwords;
	}


	#$this->{'grammaticality'} = $Align->validalignment($Varg);
=cut
	my($verbpos,$verbroot,$argpos,$argroot,$argcat,$truncpos);
	# Computing the One verb compositionality feature
	my($verbtype,$truncpos,$mi);
	for($i=0;$i<=$#$Varg;$i++)
	{
		$verbpos = $Varg->[$i]->{'position'};
		$verbroot = $engsen->{'wroot'}->[$verbpos];
		for($j=0;$j<=$#{$Varg->[$i]->{'args'}};$j++)
		{
			$argpos = $Varg->[$i]->{'args'}->[$j]->{'position'};
			$argprep = $Varg->[$i]->{'args'}->[$j]->{'prep'};


			$argroot = $engsen->{'wroot'}->[$argpos];
			$argcat = $engsen->{'pos'}->[$argpos];
			$argcat =~/^(.)/;
			$truncpos = $1;

			# Merge based features

			if($Align->{'aln'}->[$verbpos] eq $Align->{'aln'}->[$argpos] || $Align->{'aln'}->[$verbpos] eq "-" || $Align->{'aln'}->[$argpos] eq "-")
			#if($Align->{'aln'}->[$verbpos] eq $Align->{'aln'}->[$argpos] && $Align->{'aln'}->[$verbpos] ne "-" && $Align->{'aln'}->[$verbpos] ne "")
			{

				$mi = 0; 

				$mi = $cacheMI{"$verbroot $argprep $argroot"};
				if(!$mi)
				{
					$mi = $MI{"$verbroot $argprep $argroot"};
					if($mi)
					{ $cacheMI{"$verbroot $argprep $argroot"} = $mi;  }
				}

				$mi = abs(int($mi + 0.5 * ($number <=> 0)));
			
				if($mi<3)
				{
					$this->{"merge_$truncpos\_LOW"} = 1;
				}
				elsif($mi<6)
				{
					$this->{"merge_$truncpos\_MED"} = 1;
				}
				else
				{
					$this->{"merge_$truncpos\_HIGH"} = 1;
				}
			}
		}
	}

=cut
=cut
	my($verbpos,$verbroot,$argroot,$argpos,$argcat,$argprep);
	my($verbtype,$truncpos,$mi,$dist);

	for($i=0;$i<=$#$Varg;$i++)
	{
		$verbpos = $Varg->[$i]->{'position'};
		$verbroot = $engsen->{'wroot'}->[$verbpos];

		for($j=0;$j<=$#{$Varg->[$i]->{'args'}};$j++)
		{
			$argpos = $Varg->[$i]->{'args'}->[$j]->{'position'};
			$argprep = $Varg->[$i]->{'args'}->[$j]->{'prep'};

			$argroot = $engsen->{'wroot'}->[$argpos];
			$argcat = $engsen->{'pos'}->[$argpos];
			$argcat =~/^(.)/;
			$truncpos = $1;

			if($Align->{'aln'}->[$verbpos] ne "-" && $Align->{'aln'}->[$argpos] ne "-")
			{
				$dist = $Align->{'aln'}->[$verbpos] - $Align->{'aln'}->[$argpos];
				$dist = &r(($dist+1)/$nhinwords,2);
				$this->{"varg_$truncpos"} = $dist;
			}
		}
	}



	my($word1pos,$word1index,$word2pos,$word2index);
	my($trunc1pos,$trunc2pos);
	my($dist,$distsrc);
	for($i=1;$i<$nengwords;$i++)
	{
		if($Align->{'aln'}->[$i] ne "-")
		{
			$word2pos = $engsen->{'pos'}->[$i];
			$word2pos =~/^(.)/g; $trunc2pos = $1;
			$word2index = $i;

			if($word1pos ne "")
			{
				$dist = $Align->{'aln'}->[$word2index] - $Align->{'aln'}->[$word1index];
				$distsrc = $word2index - $word1index;

				$dist = ($dist+1)/$nhinwords;
				#$dist = &r(($dist+1)/$nhinwords,2);

				if($dist>=0)
				{
					$this->{"direct_$trunc1pos\_$trunc2pos"} = 1;
				}
				else
				{
					$this->{"direct_$trunc1pos\_$trunc2pos"} = -1;
				}

				$this->{"mag_$trunc1pos\_$trunc2pos"} = abs($dist);

				#if($dist>=0)
				#{ $this->{"direc_$trunc1pos\_$trunc2pos"} = $dist; }
				#elsif($dist<0)
				#{ $this->{"direc_$trunc1pos\_$trunc2pos"} = $dist; }

				#if($dist==0)
				#{ $this->{"merge_$word1pos\_$word2pos"} = 1; }

			}
			$word1pos=$word2pos;
			$trunc1pos = $trunc2pos;
			$word1index = $word2index;

		}

	}

	my($word1pos,$word1index,$word2pos,$word2index);
	my($trunc1pos,$trunc2pos);
	my($dist,$distsrc);
	for($i=1;$i<$nengwords;$i++)
	{
		if($Align->{'aln'}->[$i] ne "-" && $Align->{'aln'}->[$i-1] ne "-")
		{
			$word2pos = $engsen->{'pos'}->[$i];
			$word2pos =~/^(.)/g; $trunc2pos = $1;

			$word1pos = $engsen->{'pos'}->[$i-1];
			$word1pos =~/^(.)/g; $trunc1pos = $1;

			$dist = $Align->{'aln'}->[$i] - $Align->{'aln'}->[$i-1];
			if($dist==0)
			{
				$this->{"merge_$word1pos\_$word2pos"} = 1;
			}
			elsif($dist==-1)
			{
				$this->{"reverse_$word1pos\_$word2pos"} = 1;
			}
			elsif($dist==1)
			{
				$this->{"straight_$word1pos\_$word2pos"} = 1;
			}
		}
	}
=cut
=cut

	my($p,$q);
	my($avgdist,$totelem);
	for($win=2;$win<=4;$win++)
	{
	$window = $win;
	for($i=$window-1;$i<$nengwords;$i++)
	{
		$avgdist = 0;
		$totelem = 0;
		for($p=$i-2+1;$p<=$i;$p++)
		{
			for($q=$p+1;$q<=$i;$q++)
			{
				if($Align->{'aln'}->[$p] ne "-" && $Align->{'aln'}->[$q] ne "-")
				{
					$dist = abs($Align->{'aln'}->[$p] - $Align->{'aln'}->[$q]);
					$totelem ++;
				}
			}
		}
		if($totelem)
		{  $this->{"windist_$window"} += $dist/$totelem; }
	
	}
	}
=cut
}

sub getFeatures {
	my($this) = shift;
	my($engsen) = shift;
	my($hinsen) = shift;
	my($Align) = shift;
	my($Varg) = shift;
	my($Dep) = shift;
	my($nengwords) = $#{$engsen->{'word'}}+1;
	my($nhinwords) = $#{$hinsen->{'word'}}+1;

	my($FCONF) = $ENV{'FCONF'};

	my($i,$j,$p);	
	my($LFeatures);
	my($GFeatures);
	my($avvb_dist,$av,$tot,$overlap);

	for($i=0;$i<$nengwords;$i++)
	{
		$LFeatures = new Features;
		$LFeatures->getLFeatures($engsen,$hinsen,$i,$Align->{'aln'}->[$i]);
		$this->addFeatures($LFeatures);
	}


	#$GFeatures = new Features;
	#$GFeatures->getGFeatures($engsen,$hinsen,$Align,$Varg,$Dep);
#	$this->addFeatures($GFeatures);

}

sub get_srcposition {
	my($verbnum) = shift;
	my($argnum) = shift;
	my($Varg) = shift;
	my($j);
	my($num_between) = 1;

	if($Varg->[$verbnum]->{'args'}->[$argnum]->{'position'} < $Varg->[$verbnum]->{'position'})
	{
	for($j=0;$j<$Varg->[$verbnum]->{'Nargs'};$j++)
	{
		if($Varg->[$verbnum]->{'args'}->[$argnum]->{'position'} < $Varg->[$verbnum]->{'args'}->[$j]->{'position'} && $Varg->[$verbnum]->{'args'}->[$j]->{'position'} < $Varg->[$verbnum]->{'position'})
		{
			$num_between++;
		}
		return -1*$num_between;
	}
	}
	elsif($Varg->[$verbnum]->{'args'}->[$argnum]->{'position'} > $Varg->[$verbnum]->{'position'})
	{
	for($j=0;$j<$Varg->[$verbnum]->{'Nargs'};$j++)
	{
		if($Varg->[$verbnum]->{'args'}->[$argnum]->{'position'} > $Varg->[$verbnum]->{'args'}->[$j]->{'position'} && $Varg->[$verbnum]->{'args'}->[$j]->{'position'} > $Varg->[$verbnum]->{'position'})
		{
			$num_between++;
		}
		return $num_between;
	}
	}
}

sub addFeatures {
	my($this) = shift;
	my($Feats) = shift;
	foreach $Feat (keys %{$Feats})
	{
		$this->{$Feat} += $Feats->{$Feat};
	}
}

sub getLFeatures {
	my($this) = shift;
	my($engsen) = shift;
	my($hinsen) = shift;
	my($sword)= shift;
	my($tword) = shift;

	my($FCONF) = $ENV{'FCONF'};

	my($srcword,$srccat,$srcroot,$srcrole,$verbroot);

	$srcword = $engsen->{'word'}->[$sword];			
	$srcroot = $engsen->{'wroot'}->[$sword];			
	$srcroot = lc($srcroot);
	$srccat = $engsen->{'pos'}->[$sword];			

	if($tword eq "-")
	{
		my($srcrole);

	#	if($FCONF == 2 || $FCONF == 7) {
	#		$this->{"null_$srccat"} = 1; 
	#	}

		if($FCONF == 4 || $FCONF==5 || $FCONF==6 || $FCONF==7 || $FCONF==8) {
			$srccat=~/^(.)/g;
			$this->{"null_$1"} = 1;
		}

		$tgtword = "null";
		$tgtcat = "null";
		$tgtroot = "null";

		#return;
	}
	else
	{
		$tgtword = $hinsen->{'word'}->[$tword];			
		$tgtroot = $hinsen->{'wroot'}->[$tword];			
		$tgtcat = $hinsen->{'pos'}->[$tword];	

	}

	my($DiceWord,$DiceRoot,$DiceWordnull,$DiceRootnull,$Dictionary);

	$DiceWord = $cacheDicewd{"$srcword $tgtword"};
	if(!($DiceWord))
	{ 
		$DiceWord = $Dicewd{"$srcword $tgtword"};
		if($DiceWord)
		{ $cacheDicewd{"$srcword $tgtword"} = $DiceWord; }
	}
	if($tgtword eq "null")
	{

		$DiceWordnull = $cacheDicewdnull{"$srcword null"};
		if(!$DiceWordnull)
		{
			$DiceWordnull = $Dicewdnull{"$srcword null"};
			if($DiceWordnull)
			{ $cacheDicewdnull{"$srcword null"} = $DiceWordnull; }
		}
	}

	$DiceRoot = $cacheDicert{"$srcroot $tgtroot"};
	if(!($DiceRoot))
	{ 
		$DiceRoot = $Dicewd{"$srcroot $tgtroot"};
		if($DiceRoot)
		{ $cacheDicert{"$srcroot $tgtroot"} = $DiceRoot; }
	}
	if($tgtroot eq "null")
	{
		$DiceRootnull = $cacheDicertnull{"$srcroot null"};
		if(!$DiceRootnull)
		{
			$DiceRootnull = $Dicertnull{"$srcroot null"};
			if($DiceRootnull)
			{ $cacheDicertnull{"$srcroot null"} = $DiceRootnull; }
		}
	}

	$Dictionary = $cacheDict{"$srcroot $tgtroot"};
	if(!($Dictionary))
	{
		$Dictionary = $Dict{"$srcroot $tgtroot"};
		if($Dictionary)
		{ $cacheDict{"$srcroot $tgtroot"} = $Dictionary; }
	}

	$basic_eng_hnd = $cacheBasicEngHnd{"$srcword $tgtword"};
	if(!($basic_eng_hnd))
	{
		$basic_eng_hnd = $BasicEngHnd{"$srcword $tgtword"};
		if($basic_eng_hnd)
		{ $cacheBasicEngHnd{"$srcword $tgtword"} = $basic_eng_hnd; }
	}

	$basic_hnd_eng = $cacheBasicHndEng{"$srcword $tgtword"};
	if(!($basic_hnd_eng))
	{
		$basic_hnd_eng = $BasicHndEng{"$srcword $tgtword"};
		if($basic_hnd_eng)
		{ $cacheBasicHndEng{"$srcword $tgtword"} = $basic_hnd_eng; }
	}

	$root_eng_hnd = $cacheRootEngHnd{"$srcroot $tgtroot"};
	if(!($root_eng_hnd))
	{
		$root_eng_hnd = $RootEngHnd{"$srcroot $tgtroot"};
		if($root_eng_hnd)
		{ $cacheRootEngHnd{"$srcroot $tgtroot"} = $root_eng_hnd; }
	}

	$root_hnd_eng = $cacheRootHndEng{"$srcroot $tgtroot"};
	if(!($root_hnd_eng))
	{
		$root_hnd_eng = $RootHndEng{"$srcroot $tgtroot"};
		if($root_hnd_eng)
		{ $cacheRootHndEng{"$srcroot $tgtroot"} = $root_hnd_eng; }
	}

	if($DiceWord) { 
		if($FCONF != 2) {
			$this->{'diceword'} = $DiceWord; 
		}
	}
	elsif($DiceWordnull) { 
		if($FCONF != 2) {
			$this->{'diceword'} = $DiceWordnull; 
		}
		if($FCONF==1 || $FCONF==3) {
			$this->{'dicewordnull'} = $DiceWordnull; 
		}
	}
	#elsif($tgtword eq "null")
	#{ $this->{'diceword'} = 2/50000; }

	if($DiceRoot) { 
		if($FCONF != 1) {
			$this->{'diceroot'} = $DiceRoot; 
		}
	}
	elsif($DiceRootnull) { 
		if($FCONF != 1) {
			$this->{'diceroot'} = $DiceRootnull; 
		}
		if($FCONF==2 || $FCONF==3) {
			$this->{'dicerootnull'} = $DiceRootnull; 
		}
	}
	#elsif($tgtroot eq "null")
	#{ $this->{'diceroot'} = 2/50000; }

	#if($DiceWord && $DiceRoot) { $this->{'diceprod'} = sqrt($DiceWord*$DiceRoot); }

	if($Dictionary) { 
		if($FCONF==5 || $FCONF==6 || $FCONF==7 || $FCONF==8 ) {
			$this->{'dictionary'} = $Dictionary; 
		}
	}

	if($FCONF==6) {
		$this->{"rt_$srcroot\_$tgtroot"} = 1;
	}


	#if($basic_eng_hnd) { $this->{'basic_eng_hnd'} = $basic_eng_hnd; }
	#if($basic_hnd_eng) { $this->{'basic_hnd_eng'} = $basic_hnd_eng; }
	#if($root_eng_hnd) { $this->{'root_eng_hnd'} = $root_eng_hnd; }
	#if($root_hnd_eng) { $this->{'root_hnd_eng'} = $root_hnd_eng; }

	# Distance Feature
	my($dist);
	if($tword ne "-")
	{
	#	$dist = abs($sword/($#{$engsen->{'word'}}+1) - $tword/($#{$hinsen->{'word'}}+1));
	#	$this->{'dist'} = $dist;

	#	my($totalequal,$consequal,$fracoverlap);
	#	$totalequal = &ifequal($srcword,$tgtword);
	#	if($totalequal) { $this->{'equal'} = 1; }
	#	$consequal = &ifconsequal($srcword,$tgtword);
	#	if($consequal) { $this->{'consequal'} = 1; }

		if($FCONF==7 || $FCONF==8) {
			$fracoverlap = &fracoverlap($srcword,$tgtword);
			if($fracoverlap) { $this->{'fracoverlap'} = 1; }
		}

	}

}

sub ifequal {
	
	my($srcword) = lc($_[0]);
	my($tgtword) = lc($_[1]);

	if($srcword eq $tgtword)
	{
		return 1;
	}
	return 0;
}

sub ifconsequal {

	my($srcword) = lc($_[0]);
	my($tgtword) = lc($_[1]);

	$srcword=~s/[aeiou,;\.\:\-\\\/\"\'\*\%\$]+//g;
	$tgtword=~s/[aeiou,;\.\:\-\\\/\"\'\*\%\$]+//g;

	if($srcword eq $tgtword)
	{
		return 1;
	}
	return 0;
}

sub fracoverlap {

        my($srcword) = $_[0];
        my($tgtword) = $_[1];

	if($srcword=~/^[^A-Z]/)
	{
		return 0;
	}


        $tgtword=~s/[\$\%\&\*\?\+\(\)\[\]\\\.]+//g;
        $tgtword=lc($tgtword);

        $tgtword=~s/[aeiou]//g;

        $tgtword=~s/w/t/g;
        $tgtword=~s/x/d/g;
        $tgtword=~s/k/c/g;
        $tgtword=~s/([a-z])m/$1n/g;
        $tgtword=~s/z/j/g;
        $tgtword=~s/p/f/g;

        $srcword=~s/[\$\%\&\*\?\+\(\)\[\]\\]//g;
        $srcword=lc($srcword);
        $srcword=~s/[aeiou]//g;
        $srcword=~s/([a-z])m/$1n/g;
        $srcword=~s/z/j/g;


        my ($longest_c, $longest,$strlen,$substr) = 0;
         for my $start (0..length $tgtword) {
            for my $len ( reverse $start+1 .. length $tgtword) {
            my $substr = substr($tgtword, $start, $len);

                while($srcword =~/($substr)/g)
                {
                        $substr = $1;
                        $strlen = length $1;
                        if($strlen > $longest_c)
                        { ($longest_c, $longest) = ($strlen, $substr); }
                }
            }
         }

        if(length($srcword)==0) { return 0; }
        return (length($longest)/(length($srcword)));
}


sub verbtype {
	my($verbroot) = shift;
	if($verbroot eq "take" || $verbroot eq "be" || $verbroot eq "make")
	{ return $verbroot; }
	return;
}

sub auxtype {
	my($root) = shift;
	my($cat) = shift;

	if($cat eq "v" && ( $root eq "WA" || $root eq "kara" || $root eq "jA" || $root  eq "raha" || $root eq "banA" || $root eq "ho" || $root eq "hE" || $root eq "jAna" || $root eq "le" || $root eq "ho" || $root eq "uTA" || $root eq "xe" ))
	{ return $root; }
	return;
}

sub preptype {
	my($root) = shift;
	my($cat) = shift;
	if($cat eq "p")
	{ return $root; }
	return 0;
}

sub dotProduct {
	my($Features1) = shift;
	my($Features2) = shift;
	my($dotproduct) = 0;
	foreach $feature (keys %{$Features1})
	{
		$dotproduct += $Features1->{$feature}*$Features2->{$feature};
	}
	return $dotproduct;
}

sub difffeatures {
	my($this) = shift;
	my($Features1) = shift;
	my($Features2) = shift;

	foreach $feature (keys %{$Features1})
	{
		$this->{$feature} = $Features1->{$feature};
	}

	foreach $feature (keys %{$Features2})
	{
		$this->{$feature} -= $Features2->{$feature};
	}
}

sub difffeatures2 {
	my($this) = shift;
	my($Features1) = shift;
	my($Features2) = shift;

	foreach $feature (keys %{$Features2})
	{
		$this->{$feature} = $Features1->{$feature} - $Features2->{$feature};
	}

}

sub r {
    my ($number,$decimals) = @_;
    return substr($number+("0."."0"x$decimals."5"),
                  0, $decimals+length(int($number))+1);
}

1;
